package com.sso.comm.cookie;

import com.google.gson.reflect.TypeToken;
import com.sso.comm.cons.Const;
import com.sso.comm.cons.ParamConst;
import com.sso.comm.domain.Ticket;
import com.sso.comm.domain.Token;
import com.sso.comm.domain.TokenBase;
import com.sso.comm.encrypt.AES;
import com.sso.comm.encrypt.SSOEncrypt;
import com.sso.comm.util.JsonHelper;
import com.sso.comm.util.IpHelper;
import com.sso.comm.util.SessionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;

public class TokenHelper extends CookieHelper {
    private static Logger logger = LoggerFactory.getLogger(TokenHelper.class);

    public static Token getToken(HttpServletRequest request) {
        String jsonTk = getJsonToken(request, AES.getInstance(), Const.cookieName);
//        String jsonTk = SessionUtils.getAttr(request,Const.cookieName);
        if (StringUtils.isBlank(jsonTk)) {
            return null;
        }
        Token tk = JsonHelper.toObj(jsonTk, new TypeToken<Token>() {
        });
        return (Token) checkIp(request, tk);
    }

    public static Ticket getTicket(HttpServletRequest request) {
        String jsonTk = getJsonToken(request, AES.getInstance(), Const.ticket_cookiename);
        if (StringUtils.isBlank(jsonTk)) {
            return null;
        }
        Ticket tk = JsonHelper.toObj(jsonTk, new TypeToken<Ticket>() {
        });
        return (Ticket) checkIp(request, tk);
    }

    /**
     * <p>
     * 校验Token IP 与登录 IP 是否一致
     * </p>
     *
     * @param request
     * @param token   登录票据
     * @return Token {@link Token}
     */
    public static TokenBase checkIp(HttpServletRequest request, TokenBase token) {
        String ip = IpHelper.getIpAddr(request);
        if (token != null && ip != null && !ip.equals(token.getIp())) {
            /**
             * 检查 IP 与登录IP 不一致返回 null
             */
            logger.error("ip校验不一致");
            return null;
        }
        return token;
    }

    /**
     * <p>
     * 获取当前请求 JsonToken
     * </p>
     *
     * @param request
     * @param encrypt    对称加密算法类
     * @param cookieName Cookie名称
     * @return String 当前Token的json格式值
     */
    public static String getJsonToken(HttpServletRequest request, SSOEncrypt encrypt, String cookieName) {
        Cookie uid = CookieHelper.findCookieByName(request, cookieName);
        if (uid != null) {
            String jsonToken = uid.getValue();
            String[] tokenAttr = new String[2];
            try {
                jsonToken = encrypt.decrypt(jsonToken, ParamConst.AES_KEY);
                tokenAttr = jsonToken.split(Const.CUT_SYMBOL);
            } catch (Exception e) {
                logger.error("AES解密出错");
            }
            return tokenAttr[0];
        }
        return null;
    }

    /**
     * 生成跨域回复票据
     *
     * @param request
     * @param askData
     * @return
     */
    public static Ticket replyCiphertext(HttpServletRequest request, String askData) {
        String str = null;
        try {
            str = AES.getInstance().decrypt(askData, ParamConst.AES_KEY);
        } catch (Exception e) {
            logger.info("replyCiphertext AES decrypt error.\n" + e.toString());
        }
        if (str != null) {
            /*
             * <p> 使用业务系统公钥验证签名 </p> <p> 验证 IP 地址是否合法 </p>
			 */
            Ticket at = JsonHelper.toObj(str, new TypeToken<Ticket>() {
            });
            if (checkIp(request, at) != null) {
                return at;
            }
        }
        return null;
    }

    public static void main(String[] args) throws Exception {
        String secret = AES.getInstance().encrypt("123jc是天才", ParamConst.AES_KEY);
        // String secret2 = AES.getInstance().encrypt("123jc是天才2",
        // Const.Secretkey);
        System.out.println(secret);
        System.out.println(AES.getInstance().decryptAES(secret));
    }
}
